
#! /usr/bin/python

import sys
import os
import time
import random
#sys.path.append('..'+os.sep+'trunk')
sys.path.append('../../../')
from spade import *
class Example(Agent.Agent):
    def _setup(self):
        entry = "Starting Organization Behaviour"
     #   self.info=[{"Recurso":"Restaurant","Nombre":"Restaurante1","type":"Italiano","Calle":"lacalle"}]


    def _process(self):
       pass
class MyCoalition(Organization.Coalition):
    def onStart(self):
        if self.owner:
            #unit creation
            self.unit=MyTeam(agent=self.myAgent, nick=self.myAgent.nick, name=self.myAgent.nick,password="pass",agentList=[])
            o.addUnit(self.unit)
            #anyadimos un comportamiento que actualiza el precio
            self.actualiza=self.ActualizaPrecio(self)
            self.myAgent.addBehaviour(self.actualiza)
    def _process(self):
        if self.owner:
            time.sleep(self.myAgent.time)
            print "Cerramos la unidad "
            self.unit.entrada=False
            time.sleep(3)
            self.myAgent.removeBehaviour(self.actualiza)
            self.destroy()

    class ActualizaPrecio(Behaviour.Behaviour):
        def __init__(self,org):
            self.org=org
            self.precio=""
            self.old_precio=""
            Behaviour.Behaviour.__init__(self)

        def _process(self):
            time.sleep(5)
            while 1:
                self.old_precio=self.precio
                self.precio=self.org.unit.consultaPrecio()
                if self.precio!=self.old_precio:
                    self.org.setGoal({"buy":b.producto,"price":self.precio})
                    print "Nuevo Precio ",self.precio

class MyTeam(Unit.Team):
    def onStart(self):
        if self.owner:
            self.unidades=self.myAgent.units
            self.time=self.myAgent.time
            self.vendedor=self.myAgent.vendedor
            self.entrada=True
            self.precio=""

    #def _process(self):
        #if self.owner:
            #print "Tiempo para realizar la compra ",self.time
             #print "Unidades que se desea comprar ",self.unidades
            #time.sleep(self.myAgent.time)
            #print "Cerramos la unidad "
            #self.entrada=False
            #time.sleep(3)
            #print "Unidades que se desea comprar ",self.unidades
            #self.destroy()
    def onEnd(self):
        if self.owner:
            print "Compra de ",self.myAgent.producto," al precio->",self.precio
    def consultaPrecio(self):
        vendedor=[]
        dad = DF.DfAgentDescription()
        ds = DF.ServiceDescription()
        ds.setType("Venta")
        ds.setName(self.myAgent.producto)
        dad.addService(ds)
        search = b.searchService(dad)
        if search:
            for s in search:
                vendedor.append(s.getAID())
        min=""
        for v in vendedor:
            id=random.randint(0,10000)
            template = Behaviour.ACLTemplate()
            template.setPerformative("inform")
            template.setOntology("Consulta")
            template.setConversationId(id)
            t = Behaviour.MessageTemplate(template)
            self.setTemplate(t)
            #print "Voy a consultar el precio que me cuestan las ",self.unidades
            ans=ACLMessage.ACLMessage()
            ans.setPerformative("request")
            ans.setOntology("Consulta")
            ans.setSender(self.myAgent.getAID())
            ans.addReceiver(v)
            ans.setContent(str(self.unidades))
            ans.setConversationId(id)
            self.myAgent.send(ans)
            #print ans
            m= self._receive(True)
            while not m:
               m= self._receive(True)
            precio=float(m.getContent())
            if not min or precio<min:
                min=precio
                self.myAgent.vendedor=v
        self.precio=min
        return min

    def entryUnitTest(self,sender,desc=None):
      type=""
      subtype=""
      for l in desc:
          if l["name"]=="units":
              u=str(l["value"])
              u=int(u)
              self.unidades=self.unidades+u
              return self.entrada
      return False


if __name__ == "__main__":
    a="comprador"
    if len(sys.argv)>1:
        max=sys.argv[1]
    else: max=5
    max=int(max)+1
    for n in xrange(1,max):
        agent = a+str(n)+"@apolo.dsic.upv.es"
        #agent = "agent@thx1138.dsic.upv.es"
        #agent = "agent@tatooine.dsic.upv.es"
        b = Example(agent,"pasword")
        l=["ProductoA","ProductoB","ProductoC"]
        b.producto=l[random.randint(0,2)]
        b.nick=a+str(n)
        b.units=random.randint(1,50)
        b.time=random.randint(50,200)
        #b.time=100
        b.start()
        b.nick=a+str(n)
        b.vendedor=""
        #print "Agent "+agent+" registering"
        time.sleep(2)
        continua=True
        while continua:
            while not b.vendedor:
                dad = DF.DfAgentDescription()
                ds = DF.ServiceDescription()
                ds.setType("Venta")
                ds.setName(b.producto)
                dad.addService(ds)
                search = b.searchService(dad)
                if search:
                    dad=search[0]
                    b.vendedor=dad.getAID()
            lista= b.getOrganizationList()
            #print lista
            create=True
            if b.producto in lista:
                create=False
            try:
                if not create:
                    o=MyCoalition(b,nick=b.nick, name=b.producto)
                    b.joinOrganization(o)
                    l=o.getUnitList()
                    for u in l:
                        d=[{"name":"units","value":b.units}]
                        entry=o.requestEntryUnit(u,d)
                        if not entry:
                           entry=o.requestEntryUnit(u,d)
                        if entry:
                            unit=MyTeam(b, nick=b.nick, name=u,password=entry)
                            o.joinUnit(unit)
                else:
                    o=MyCoalition(agent=b,nick=b.nick,name=b.producto)
                    b.createOrganization(o)
                    o.setGoal({"buy":b.producto})
                continua=False
            except Unit.Unavailable:
                print "Unavailable"
            except:
                print "Excepcion"
                continua=True
        time.sleep(5)








